<BASE HREF="http://support.microsoft.com/support/kb/articles/q190/3/51.asp">

<HTML>
<HEAD>
<TITLE>Q190351 - HOWTO: Spawn Console Processes with Redirected Standard Handles</TITLE>
<META HTTP-EQUIV="CONTENT-Type" CONTENT="text/html; charset=iso-8859-1" />
<META HTTP-EQUIV="PICS-Label" CONTENT="(PICS-1.1 &quot;http://www.rsac.org/ratingsv01.html&quot; l gen true comment &quot;RSACi North America Server&quot; by &quot;Inet@microsoft.com&quot; for &quot;http://support.microsoft.com&quot; on &quot;1998.02.17T12:28-0800&quot; r (n 0 s 0 v 0 l 0))" />
<META NAME="ms.locale" CONTENT="EN-US" />
<META NAME="Category" CONTENT="Support; KB Article" />
<META NAME="Premium" CONTENT="Support" />
<META NAME="KBArea" CONTENT="Support; KB; win32sdk; kbWinNTsearch; kbWinNTWsearch; kbWinNTW400; kbWinNTW400search; kbWinNT351xsearch; kbWinNT400xsearch; kbWinNTW351xsearch; kbWinNTW351; kbWinNTSsearch; kbWinNTS400xsearch; kbWinNTS400; kbWinNTS351; kbWinNTS351xsearch; kbOSWinNT; kbOSWinSearch; " />
<META NAME="KBID" CONTENT="Q190351" />
<META NAME="KBTitle" CONTENT="HOWTO: Spawn Console Processes with Redirected Standard Handles" />
<META NAME="Description" CONTENT="This article describes how to redirect the input and output of a child process that receives input from the standard input handle or sends output to the standard output handle. The Win32 API enables applications to spawn a child console pro" />
<META NAME="Product" CONTENT="win32sdk" />
<META NAME="KBCreate" CONTENT="July 27, 1998" />
<META NAME="KBModify" CONTENT="December 14, 2000" />
<META NAME="EditDate" CONTENT="April 30, 1999" />
<META NAME="Question" CONTENT="" />
<META NAME="Versions" CONTENT="winnt:3.51,4.0" />
<META NAME="Component" CONTENT="" />
<META NAME="Technology" CONTENT="kbWinNTsearch kbWinNTWsearch kbWinNTW400 kbWinNTW400search kbWinNT351xsearch kbWinNT400xsearch kbWinNTW351xsearch kbWinNTW351 kbWinNTSsearch kbWinNTS400xsearch kbWinNTS400 kbWinNTS351 kbWinNTS351xsearch kbOSWinNT kbOSWinSearch" />
<META NAME="Links" CONTENT="150956" />
<META NAME="Keywords" CONTENT="kbAPI kbConsole kbIPC kbKernBase kbOSWinNT400 kbOSWin2000 kbSDKPlatform kbOSWin95 kbOSWin98 kbfaq kbDSupport kbGrpDSKernBase" />
<META NAME="Platform" CONTENT="" />
<META NAME="Hardware" CONTENT="" />
<META NAME="SolutionType" CONTENT="" />
<META NAME="IssueType" CONTENT="kbhowto" />
<META NAME="BoilerPlate" CONTENT="" />
<META NAME="ProducedView" CONTENT="" />
<META NAME="QUERYWORDS" CONTENT="Inheritance">
<META NAME="QUERYWORDS" CONTENT="redirection">
<META NAME="QUERYWORDS" CONTENT="redirected">
<META NAME="QUERYWORDS" CONTENT="stdhandles">

</HEAD>
<LINK REL="STYLESHEET" TYPE="text/css" HREF="/support/include/style.css" />
<BODY BGCOLOR="#FFFFFF" LEFTMARGIN="0" MARGINHEIGHT="0" MARGINWIDTH="0" RIGHTMARGIN="0" TOPMARGIN="0">
<!-- Do not redirect KB Articles to the XMLStore at this time -->


<!--TOOLBAR_START-->
<A NAME="TOP" />
<A NAME="TOP"></A>
<!-- Start: ToolBar V2.0-->

<!--TOOLBAR_EXEMPT-->
<SCRIPT LANGUAGE="JavaScript" SRC="/isapi/gosupport.asp?target=/library/toolbar/toolbar.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="/isapi/gosupport.asp?target=/library/toolbar/EN-US/global.js "></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="/isapi/gosupport.asp?target=/include/toolbar/EN-US_local.js"></SCRIPT>

<!-- Start: ToolBar for down-level browsers-->
<SPAN ID="TBDownLevelDiv">
<TABLE WIDTH="100%" CELLPADDING="0" CELLSPACING="0" BORDER="0" BGCOLOR="#FFFFFF">
<TR>
	<TD VALIGN="TOP" HEIGHT="60" ROWSPAN="2" WIDTH="100%"><A HREF="/isapi/gosupport.asp?target=/directory/default.asp"><IMG SRC="/isapi/gosupport.asp?target=/library/images/support/pss_EN-US.gif" BORDER=0 ALT="Microsoft Product Support Services"></A></TD>
	<TD VALIGN="TOP" HEIGHT="20" ALIGN="RIGHT"><IMG SRC="/isapi/gosupport.asp?target=/library/toolbar/images/curve.gif" WIDTH=18 HEIGHT=20 BORDER=0 ALT=""></TD>

<!--Start Global Toolbar Section-->
<TD BGCOLOR="#000000" HEIGHT="20" VALIGN="MIDDLE" ALIGN="RIGHT" NOWRAP COLSPAN="2">
  <FONT COLOR="#FFFFFF" FACE="Verdana, Arial" SIZE="1">
  <B>
   &nbsp;&nbsp;<A STYLE="color:#FFFFFF;text-decoration:none;" HREF="/isapi/gomscom.asp?target=/products/" TARGET="_top"><FONT COLOR="#FFFFFF">All Products</FONT></A>&nbsp;&nbsp;<FONT COLOR="#FFFFFF">|</FONT>
   &nbsp;&nbsp;<A STYLE="color:#FFFFFF;text-decoration:none;" HREF="/isapi/gosupport.asp?target=/directory/default.asp?fr=0&sd=gn" TARGET="_top"><FONT COLOR="#FFFFFF">Support</FONT></A>&nbsp;&nbsp;<FONT COLOR="#FFFFFF">|</FONT>
   &nbsp;&nbsp;<A STYLE="color:#FFFFFF;text-decoration:none;" HREF="/isapi/gosearch.asp?target=/" TARGET="_top"><FONT COLOR="#FFFFFF">Search</FONT></A>&nbsp;&nbsp;<FONT COLOR="#FFFFFF">|</FONT>
   &nbsp;&nbsp;<A STYLE="color:#FFFFFF;text-decoration:none;" HREF="/isapi/gomscom.asp?target=/" TARGET="_top"><FONT COLOR="#FFFFFF">microsoft.com Home</FONT></A>&nbsp;&nbsp;
  </B>
  </FONT></TD>
<!--End Global Toolbar Section-->

</TR>
<TR>
	<TD VALIGN="TOP" HEIGHT=40 WIDTH=19><IMG SRC="/isapi/gosupport.asp?target=/library/images/gifs/homepage/1ptrans.gif" WIDTH=19 HEIGHT=40 BORDER=0></TD>
	<TD VALIGN="TOP" HEIGHT=40 ALIGN="RIGHT" NOWRAP COLSPAN=2><A HREF="/isapi/gomscom.asp?target=/" TARGET="_top"><IMG SRC="/isapi/gosupport.asp?target=/library/toolbar/images/mslogo.gif" WIDTH=112 HEIGHT=40 ALT="microsoft.com" BORDER=0></A></TD>
</TR>
<!-- Start: Black Line Spacer  -->
<TR>
	<TD BGCOLOR="#000000" HEIGHT=1 NOWRAP COLSPAN=4></TD>
</TR>
<!-- End: Black Line Spacer -->
<TR>
	<!-- Start: Local menus -->
	<TD BGCOLOR="#000000" HEIGHT=20 VALIGN="MIDDLE" NOWRAP COLSPAN=4>
		<FONT COLOR="#FFFFFF" FACE="Verdana, Arial" SIZE=1><B>

			&nbsp;&nbsp;<A STYLE="color:#FFFFFF;text-decoration:none;" HREF="/isapi/gosupport.asp?target=/directory/default.asp" TARGET="_top" TITLE="Home"><FONT COLOR="#FFFFFF">Support Home</FONT></A>&nbsp;&nbsp;<FONT COLOR="#FFFFFF">|</FONT>

			&nbsp;&nbsp;<A STYLE="color:#FFFFFF;text-decoration:none;" HREF="/isapi/gosupport.asp?target=/directory/self.asp?ln=en-us&sd=gn&amp;fr=0" TARGET="_top" TITLE="Find a Solution"><FONT COLOR="#FFFFFF">Find a Solution</FONT></A>&nbsp;&nbsp;<FONT COLOR="#FFFFFF">|</FONT>

			&nbsp;&nbsp;<A STYLE="color:#FFFFFF;text-decoration:none;" HREF="/isapi/gosupport.asp?target=/directory/directory.asp?ln=en-us&sd=gn" TARGET="_top" TITLE="Request Support"><FONT COLOR="#FFFFFF">Request Support</FONT></A>&nbsp;&nbsp;<FONT COLOR="#FFFFFF">|</FONT>

			&nbsp;&nbsp;<A STYLE="color:#FFFFFF;text-decoration:none;" HREF="/isapi/gosupport.asp?target=/directory/customer.asp?sd=gn&amp;fr=0" TARGET="_top" TITLE="Comprehensive support customized by customer type"><FONT COLOR="#FFFFFF">Custom Support</FONT></A>&nbsp;&nbsp;<FONT COLOR="#FFFFFF">|</FONT>


		</B></FONT></TD>
	<!-- End: Local menus -->
</TR>
<!-- Start: Black Line Spacer  -->
<TR>
	<TD BGCOLOR="#000000" HEIGHT=1 NOWRAP COLSPAN=4></TD>
</TR>
<!-- End: Black Line Spacer -->
</TABLE>
</SPAN>
<!-- End: ToolBar For down-level browsers-->

<SCRIPT LANGUAGE="JavaScript">
<!--// Hide from old browsers
	var ToolBar_Supported = ToolBar_Supported;
	if (ToolBar_Supported != null && ToolBar_Supported == true)
	{
		TBDownLevelDiv.style.display = "none";
		drawToolbar();
	}
//-->
</SCRIPT>
<!-- End: ToolBar V2.0-->
<!--TOOLBAR_END-->

<!--TOOLBAR_END-->
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="100%">
<TR>
<TD VALIGN="top">
<CENTER>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="95%">
<TR>
<TD VALIGN="top">
<FONT FACE="Verdana, Arial, Helvetica" SIZE="2">
<TABLE>
<TR><TD><H2>
HOWTO: Spawn Console Processes with Redirected Standard Handles</H2></TD></TR>
</TABLE>

<HR />
The information in this article applies to:<BR />
<UL><LI>
Microsoft Win32 Application Programming Interface (API), included with:<UL><LI>
the operating system: Microsoft Windows 2000</LI>
<LI>
Microsoft Windows 98</LI>
<LI>
Microsoft Windows 95</LI>
<LI>
Microsoft Windows NT Server versions  3.51, 4.0</LI>
<LI>
Microsoft Windows NT Workstation versions  3.51, 4.0</LI></UL>
</LI></UL>
<HR />
<BR /><H2>SUMMARY</H2><P>
This article describes how to redirect the input and output of a child process that receives input from the standard input handle or sends output to the standard output handle. The Win32 API enables applications to spawn a child console process with redirected standard handles. This feature allows a parent process to send and receive the input and output of the child process. 
<BR />
<BR />
<B>NOTE</B>: Some console based applications do not use the standard handles for their input/output (IO) operations. The Win32 API does not support redirection of these processes.
</P>
<BR /><H2>MORE INFORMATION</H2><P>
The CreateProcess() API through the STARTUPINFO structure enables you to
redirect the standard handles of a child console based process. If the dwFlags member is set to STARTF_USESTDHANDLES, then the following STARTUPINFO members specify the standard handles of the child console based process:
<PRE CLASS="FIXEDTEXT">
   HANDLE hStdInput - Standard input handle of the child process.
   HANDLE hStdOutput - Standard output handle of the child process.
   HANDLE hStdError - Standard error handle of the child process. </PRE>
You can set these handles to either a pipe handle, file handle, or any
handle that can do synchronous reads and writes through the ReadFile() and
WriteFile() API. The handles must be inheritable and the CreateProcess()
API must specify that inheritable handles are to be inherited by the child
process by specifying TRUE in the bInheritHandles parameter. If the parent
process only wishes to redirect one or two standard handles, specifying
GetStdHandle() for the specific handles causes the child to create the
standard handle as it normally would without redirection. For example, if
the parent process only needs to redirect the standard output and error of
the child process, then the hStdInput member of the STARTUPINFO structure is filled as follows:
<PRE CLASS="FIXEDTEXT">
   hStdInput = GetStdHandle(STD_INPUT_HANDLE); </PRE><B>NOTE</B>: Child processes that use such C run-time functions as printf() and fprintf() can behave poorly when redirected. The C run-time functions
maintain separate IO buffers. When redirected, these buffers might not be
flushed immediately after each IO call. As a result, the output to the
redirection pipe of a printf() call or the input from a getch() call is not
flushed immediately and delays, sometimes-infinite delays occur. This problem is avoided if the child process flushes the IO buffers after each call to a C run-time IO function. Only the child process can flush its C run-time IO buffers. A process can flush its C run-time IO buffers by calling the fflush() function.<BR />
<BR />
<B>NOTE</B>: Windows 95 and Windows 98 require an extra step when you redirect the standard handles of certain child processes. For additional information, please see the following article in the Microsoft Knowledge Base:
<BLOCKQUOTE><A CLASS="LINK" HREF="/support/kb/articles/Q150/9/56.ASP">Q150956</A>
INFO: Redirection Issues on Windows 95 MS-DOS Applications
</BLOCKQUOTE>

The following sample redirects the standard input, output, and error of the
child process specified in the CreateProcess call. This sample redirects
the provided console process (Child.c).
<H3>Sample Code</H3>
<PRE CLASS="CODESAMP">
   /*++

      Copyright (c) 1998  Microsoft Corporation

      Module Name:

         Redirect.c

      Description:
          This sample illustrates how to spawn a child console based
          application with redirected standard handles.

          The following import libraries are required:
          user32.lib

      Dave McPherson (davemm)   11-March-98

   --*/ 

   #include&lt;windows.h&gt;

   void DisplayError(char *pszAPI);
   void ReadAndHandleOutput(HANDLE hPipeRead);
   void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut,
                                     HANDLE hChildStdIn,
                                     HANDLE hChildStdErr);
   DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam);

   HANDLE hChildProcess = NULL;
   HANDLE hStdIn = NULL; // Handle to parents std input.
   BOOL bRunThread = TRUE;


   void main ()
   {
      HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
      HANDLE hInputWriteTmp,hInputRead,hInputWrite;
      HANDLE hErrorWrite;
      HANDLE hThread;
      DWORD ThreadId;
      SECURITY_ATTRIBUTES sa;


      // Set up the security attributes struct.
      sa.nLength= sizeof(SECURITY_ATTRIBUTES);
      sa.lpSecurityDescriptor = NULL;
      sa.bInheritHandle = TRUE;


      // Create the child output pipe.
      if (!CreatePipe(&amp;hOutputReadTmp,&amp;hOutputWrite,&amp;sa,0))
         DisplayError("CreatePipe");


      // Create a duplicate of the output write handle for the std error
      // write handle. This is necessary in case the child application
      // closes one of its std output handles.
      if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
                           GetCurrentProcess(),&amp;hErrorWrite,0,
                           TRUE,DUPLICATE_SAME_ACCESS))
         DisplayError("DuplicateHandle");


      // Create the child input pipe.
      if (!CreatePipe(&amp;hInputRead,&amp;hInputWriteTmp,&amp;sa,0))
         DisplayError("CreatePipe");


      // Create new output read handle and the input write handles. Set
      // the Properties to FALSE. Otherwise, the child inherits the
      // properties and, as a result, non-closeable handles to the pipes
      // are created.
      if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
                           GetCurrentProcess(),
                           &amp;hOutputRead, // Address of new handle.
                           0,FALSE, // Make it uninheritable.
                           DUPLICATE_SAME_ACCESS))
         DisplayError("DupliateHandle");

      if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
                           GetCurrentProcess(),
                           &amp;hInputWrite, // Address of new handle.
                           0,FALSE, // Make it uninheritable.
                           DUPLICATE_SAME_ACCESS))
      DisplayError("DupliateHandle");


      // Close inheritable copies of the handles you do not want to be
      // inherited.
      if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
      if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");


      // Get std input handle so you can close it and force the ReadFile to
      // fail when you want the input thread to exit.
      if ( (hStdIn = GetStdHandle(STD_INPUT_HANDLE)) ==
                                                INVALID_HANDLE_VALUE )
         DisplayError("GetStdHandle");

      PrepAndLaunchRedirectedChild(hOutputWrite,hInputRead,hErrorWrite);


      // Close pipe handles (do not continue to modify the parent).
      // You need to make sure that no handles to the write end of the
      // output pipe are maintained in this process or else the pipe will
      // not close when the child process exits and the ReadFile will hang.
      if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle");
      if (!CloseHandle(hInputRead )) DisplayError("CloseHandle");
      if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle");


      // Launch the thread that gets the input and sends it to the child.
      hThread = CreateThread(NULL,0,GetAndSendInputThread,
                              (LPVOID)hInputWrite,0,&amp;ThreadId);
      if (hThread == NULL) DisplayError("CreateThread");


      // Read the child's output.
      ReadAndHandleOutput(hOutputRead);
      // Redirection is complete


      // Force the read on the input to return by closing the stdin handle.
      if (!CloseHandle(hStdIn)) DisplayError("CloseHandle");


      // Tell the thread to exit and wait for thread to die.
      bRunThread = FALSE;

      if (WaitForSingleObject(hThread,INFINITE) == WAIT_FAILED)
         DisplayError("WaitForSingleObject");

      if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle");
      if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle");
   }


   /////////////////////////////////////////////////////////////////////// 
   // PrepAndLaunchRedirectedChild
   // Sets up STARTUPINFO structure, and launches redirected child.
   /////////////////////////////////////////////////////////////////////// 
   void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut,
                                     HANDLE hChildStdIn,
                                     HANDLE hChildStdErr)
   {
      PROCESS_INFORMATION pi;
      STARTUPINFO si;

      // Set up the start up info struct.
      ZeroMemory(&amp;si,sizeof(STARTUPINFO));
      si.cb = sizeof(STARTUPINFO);
      si.dwFlags = STARTF_USESTDHANDLES;
      si.hStdOutput = hChildStdOut;
      si.hStdInput  = hChildStdIn;
      si.hStdError  = hChildStdErr;
      // Use this if you want to hide the child:
      //     si.wShowWindow = SW_HIDE;
      // Note that dwFlags must include STARTF_USESHOWWINDOW if you want to
      // use the wShowWindow flags.


      // Launch the process that you want to redirect (in this case,
      // Child.exe). Make sure Child.exe is in the same directory as
      // redirect.c launch redirect from a command line to prevent location
      // confusion.
      if (!CreateProcess(NULL,"Child.EXE",NULL,NULL,TRUE,
                         CREATE_NEW_CONSOLE,NULL,NULL,&amp;si,&amp;pi))
         DisplayError("CreateProcess");


      // Set global child process handle to cause threads to exit.
      hChildProcess = pi.hProcess;


      // Close any unnecessary handles.
      if (!CloseHandle(pi.hThread)) DisplayError("CloseHandle");
   }


   /////////////////////////////////////////////////////////////////////// 
   // ReadAndHandleOutput
   // Monitors handle for input. Exits when child exits or pipe breaks.
   /////////////////////////////////////////////////////////////////////// 
   void ReadAndHandleOutput(HANDLE hPipeRead)
   {
      CHAR lpBuffer[256];
      DWORD nBytesRead;
      DWORD nCharsWritten;

      while(TRUE)
      {
         if (!ReadFile(hPipeRead,lpBuffer,sizeof(lpBuffer),
                                          &amp;nBytesRead,NULL) || !nBytesRead)
         {
            if (GetLastError() == ERROR_BROKEN_PIPE)
               break; // pipe done - normal exit path.
            else
               DisplayError("ReadFile"); // Something bad happened.
         }

         // Display the character read on the screen.
         if (!WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),lpBuffer,
                           nBytesRead,&amp;nCharsWritten,NULL))
            DisplayError("WriteConsole");
      }
   }


   /////////////////////////////////////////////////////////////////////// 
   // GetAndSendInputThread
   // Thread procedure that monitors the console for input and sends input
   // to the child process through the input pipe.
   // This thread ends when the child application exits.
   /////////////////////////////////////////////////////////////////////// 
   DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam)
   {
      CHAR read_buff[256];
      DWORD nBytesRead,nBytesWrote;
      HANDLE hPipeWrite = (HANDLE)lpvThreadParam;

      // Get input from our console and send it to child through the pipe.
      while (bRunThread)
      {
         if(!ReadConsole(hStdIn,read_buff,1,&amp;nBytesRead,NULL))
            DisplayError("ReadConsole");

         read_buff[nBytesRead] = '\0'; // Follow input with a NULL.

         if (!WriteFile(hPipeWrite,read_buff,nBytesRead,&amp;nBytesWrote,NULL))
         {
            if (GetLastError() == ERROR_NO_DATA)
               break; // Pipe was closed (normal exit path).
            else
            DisplayError("WriteFile");
         }
      }

      return 1;
   }


   /////////////////////////////////////////////////////////////////////// 
   // DisplayError
   // Displays the error number and corresponding message.
   /////////////////////////////////////////////////////////////////////// 
   void DisplayError(char *pszAPI)
   {
       LPVOID lpvMessageBuffer;
       CHAR szPrintBuffer[512];
       DWORD nCharsWritten;

       FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
                NULL, GetLastError(),
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR)&amp;lpvMessageBuffer, 0, NULL);

       wsprintf(szPrintBuffer,
         "ERROR: API    = %s.\n   error code = %d.\n   message    = %s.\n",
                pszAPI, GetLastError(), (char *)lpvMessageBuffer);

       WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),szPrintBuffer,
                     lstrlen(szPrintBuffer),&amp;nCharsWritten,NULL);

       LocalFree(lpvMessageBuffer);
       ExitProcess(GetLastError());
   }

   ////////////////////////////////////////////////////////////////////// 
   // child.c
   // Echoes all input to stdout. This will be redirected by the redirect
   // sample. Compile and build child.c as a Win32 Console application and
   // put it in the same directory as the redirect sample.
   // 
   #include&lt;windows.h&gt;
   #include&lt;stdio.h&gt;
   #include&lt;string.h&gt;

   void main ()
   {
      FILE*    fp;
      CHAR     szInput[1024];


      // Open the console. By doing this, you can send output directly to
      // the console that will not be redirected.

      fp = fopen("CON", "w");
      if (!fp) {
         printf("Error opening child console - perhaps there is none.\n");
         fflush(NULL);
      }
      else
      {

      // Write a message direct to the console (will not be redirected).

         fprintf(fp,"This data is being printed directly to the\n");
         fprintf(fp,"console and will not be redirected.\n\n");
         fprintf(fp,"Since the standard input and output have been\n");
         fprintf(fp,"redirected data sent to and from those handles\n");
         fprintf(fp,"will be redirected.\n\n");
         fprintf(fp,"To send data to the std input of this process.\n");
         fprintf(fp,"Click on the console window of the parent process\n");
         fprintf(fp,"(redirect), and enter data from it's console\n\n");
         fprintf(fp,"To exit this process send the string 'exit' to\n");
         fprintf(fp,"it's standard input\n");
         fflush(fp);
      }

      ZeroMemory(szInput,1024);
      while (TRUE)
      {
         gets(szInput);
         printf("Child echoing [%s]\n",szInput);
         fflush(NULL);  // Must flush output buffers or else redirection
                        // will be problematic.
         if (!_stricmp(szInput,"Exit") )
            break;

         ZeroMemory(szInput,strlen(szInput) );

      }
   } </PRE></P>
<BR /><H2>REFERENCES</H2><P>
MSDN Library SDK documentation: CreateProcess(); STARTUPINFO structure
<BR />
<BR />

Inherit sample in the Win32 Platform SDK under:
<PRE CLASS="FIXEDTEXT">
   \MSSDK\samples\winbase\ipc\inherit </PRE></P>
<P>Additional query words: 
Inheritance redirection redirected stdhandles </P>
</FONT><FONT FACE="Verdana, Arial, Helvetica" SIZE="1">
<P>
Keywords          : kbAPI kbConsole kbIPC kbKernBase kbOSWinNT400 kbOSWin2000 kbSDKPlatform kbOSWin95 kbOSWin98 kbfaq kbDSupport kbGrpDSKernBase <BR />
Issue type        : kbhowto <BR />
Technology        : kbWinNTsearch kbWinNTWsearch kbWinNTW400 kbWinNTW400search kbWinNT351xsearch kbWinNT400xsearch kbWinNTW351xsearch kbWinNTW351 kbWinNTSsearch kbWinNTS400xsearch kbWinNTS400 kbWinNTS351 kbWinNTS351xsearch kbOSWinNT kbOSWinSearch </P>
<!--CONVLEGACY DELIMITER-->
</FONT>
</TD>
</TR>
</TABLE>
<P>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="100%">
<TR>
<TD VALIGN="top">
<CENTER>
<BR />
<FONT FACE="Verdana, Arial, Helvetica" SIZE="1">

Last Reviewed: December 14, 2000<BR />
<A HREF="/support/misc/cpyright.asp">
&copy;
2001
Microsoft Corporation. All rights reserved. Terms of Use.</A><BR />
</FONT>
</CENTER>
</TD>
</TR>
</TABLE>
</P>
</CENTER>
</TD>
<TD BGCOLOR="#003399" VALIGN="top" WIDTH="1"><IMG BORDER="0" HEIGHT="100%" SRC="/library/images/support/1ptrans.gif" WIDTH="1" /></TD>
<TD VALIGN="top" WIDTH="135">
<CENTER>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="90%">
<TR>
<TD VALIGN="top">
<FONT FACE="Verdana, Arial, Helvetica" SIZE="1">
<BR />
<P>
						Article ID: Q190351</P>
<P>
<B>Last Reviewed:</B><BR />
December 14, 2000
</P>

<P>
<A HREF="mailto:?subject=Microsoft Knowledge Base Article - q190351&body=This article pointer was forwarded to you from the Microsoft Online Support site. http://support.microsoft.com/support/kb/articles/q190/3/51.asp" TITLE="Send this article to a friend"><IMG ALIGN="absmiddle" BORDER="0" HEIGHT="10" SRC="/library/images/support/icoEmail.gif" WIDTH="18">Send to a friend</A><BR><BR>
<P>
Provided by<BR><A HREF="/directory/default.asp" TARGET="_top">Microsoft Product Support Services</A>
<P>
<HR />
<FORM ACTION="/support/contentvoting/voting_idc.asp" METHOD="post" NAME="VOTED" ONSUBMIT="return votingsubmit();">
<INPUT NAME="KBID" TYPE="hidden" VALUE="Q190351">
<INPUT NAME="PROD" TYPE="hidden" VALUE="Support; KB; win32sdk">
<INPUT NAME="KBAREA" TYPE="hidden" VALUE="Support; KB; win32sdk">
<INPUT NAME="SRV" TYPE="hidden" VALUE="support.microsoft.com">
<INPUT NAME="URL" TYPE="hidden" VALUE="/support/kb/articles/q190/3/51.asp">

Did the information in this article help answer your question?
<P>
<INPUT NAME="VOTE" TYPE="radio" VALUE="1">Yes<BR>
<INPUT NAME="VOTE" TYPE="radio" VALUE="2">No<BR>
<INPUT NAME="VOTE" TYPE="radio" VALUE="3">Did not apply
<P>
Please provide additional comments about this information.<BR>
(255 character max)
<BR><BR>
<TEXTAREA COLS="17" ID="COMMENTS" MAXLENGTH="255" NAME="COMMENTS" ROWS="5" STYLE="font:xx-small" WRAP="virtual"></TEXTAREA>
<BR>
<CENTER>
<INPUT ALT="Submit" BORDER="0" HEIGHT="32" SRC="/library/images/support/votesubmit.gif" TYPE="image" WIDTH="88">
</CENTER>

<SCRIPT LANGUAGE="JavaScript">
<!--//
function votingsubmit()
{
	if((document.VOTED.VOTE[0].checked == false) && (document.VOTED.VOTE[1].checked == false) && (document.VOTED.VOTE[2].checked == false)){
		alert("Please choose a voting option.");
		return false;}
	if(document.VOTED.COMMENTS.value.length > 255){
		alert("Your comment has exceeded the 255 character limit.\nPlease reduce the number of characters in your comment.");
		document.forms[0].COMMENTS.focus();
		return false;}
	else return true;
}
//-->
</SCRIPT>
</FORM>
</P>
</FONT>
</TD>
</TR>
</TABLE>
</CENTER>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
